package com.studerb.model;

import java.util.Calendar;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.studerb.dao.TimeStampedEntity;
import com.studerb.service.NewsGroupService;

public class NewsGroup extends TimeStampedEntity implements Comparable<NewsGroup> {
	private final static Logger logger = Logger.getLogger(NewsGroup.class);
	private Boolean canPost;
	private String groupName;
	private Calendar lastUpdatedHeaders;
	private Integer postsCount;
	private Boolean subscribed = false;

	public NewsGroup() {}

	public NewsGroup(String name, Integer postsCount, Boolean canPost) {
		groupName = name.toLowerCase();
		this.canPost = canPost;
		subscribed = false;
		this.postsCount = postsCount;
	}

	/**
	 * This takes a standard Usenet server's newsgroup (from LIST command) and
	 * creates a new Newsgroup object
	 * 
	 * @param line
	 *            returned from Usenet Host socket
	 * @return New Newsgroup or null if there is a parsing error
	 */
	public static NewsGroup createNewsGroup(String line) {
		try {
			String[] s = StringUtils.split(line);
			if (s.length != 4) {
				logger.warn("Error parsing group: " + line);
				return null;
			}
			String name = s[0];

			// ignore non-binary groups
			if (NewsGroupService.ONLY_BINARIES && !name.contains("binaries")) {
				return null;
			}

			Integer last = Integer.parseInt(s[1]);
			Integer first = Integer.parseInt(s[2]);
			// add 1 to because last and first are inclusive
			Integer postCount = last - first <= 0 ? 0 : last - first + 1;
			boolean canPost = s[3].equalsIgnoreCase("y") ? true : false;

			// ignore groups with less posts than mizSize setting
			if (postCount < NewsGroupService.MIN_SIZE) {
				return null;
			}
			// ignore those with long names
			if (name.length() > NewsGroupService.MAX_NAME_LENGTH) {
				logger.warn("NewsGroup name longer than max: " + name);
				return null;
			}

			return new NewsGroup(name, postCount, canPost);

		}
		catch (Exception e) {
			logger.warn("Bad NewsGroup downloaded: (" + line + ") : + " + e.getMessage());
			return null;
		}
	}

	public int compareTo(NewsGroup arg0) {
		return this.getGroupName().compareTo(arg0.getGroupName());
	};

	@Override public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		final NewsGroup other = (NewsGroup) obj;
		if (groupName == null) {
			if (other.groupName != null) {
				return false;
			}
		}
		else if (!groupName.equals(other.groupName)) {
			return false;
		}
		return true;
	}

	public Boolean getCanPost() {
		return canPost;
	}

	public String getGroupName() {
		return groupName;
	}

	public Calendar getLastUpdatedHeaders() {
		return lastUpdatedHeaders;
	}

	public Integer getPostsCount() {
		return postsCount;
	}

	public Boolean getSubscribed() {
		return subscribed;
	}

	@Override public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (groupName == null ? 0 : groupName.hashCode());
		return result;
	}

	public Boolean isSubscribed() {
		return subscribed;
	}

	public void setCanPost(Boolean canPost) {
		this.canPost = canPost;
	}

	public void setGroupName(String groupName) {
		this.groupName = groupName;
	}

	public void setLastUpdatedHeaders(Calendar lastUpdatedHeaders) {
		this.lastUpdatedHeaders = lastUpdatedHeaders;
	}

	public void setPostsCount(Integer postsCount) {
		this.postsCount = postsCount;
	}

	public void setSubscribed(Boolean subscribed) {
		this.subscribed = subscribed;
	}

	@Override public String toString() {
		return getGroupName();
	}

}
